package com.sky.service.impl;

import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.vo.*;
import io.swagger.models.auth.In;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

/**
 * @Title: ReportServiceImpl
 * @Author 贾金博
 * @Package com.sky.service.impl
 * @Date 2024/3/31 17:03
 * @description:
 */
@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private WorkspaceServiceImpl workspaceService;
    /**
     * 统计指定时间内 区间的营业额数据
     * @param begin
     * @param end
     * @return
     */
    @Override
    public TurnoverReportVO getTurnoverStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate>dateList = new ArrayList<>(); // 用于存放begin 到 end 范围内的每天的日期
        //计算指定日期的后一天
        while(!begin.equals(end)) {
            dateList.add(begin);
            begin = begin.plusDays(1);
        }
        dateList.add(end);

        TurnoverReportVO turnoverReportVO = new TurnoverReportVO();
        turnoverReportVO.setDateList(StringUtils.join(dateList, ","));
        List<Double>turnoverList = new ArrayList<>();

        for (LocalDate date : dateList) {
            //查询date 这个日期下面的 营业额 也就是状态  已完成  的订单合计
            // 开始时间 也要把时分秒给体现出来
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);// 这一天开始的时间
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX); // 这一天结束的时间
            Map map = new HashMap();
            map.put("begin", beginTime);
            map.put("end", endTime);
            map.put("status", Orders.COMPLETED);

            Double turnover = orderMapper.sumByMap(map);
            if(turnover == null) turnover = 0.0; // 注意 要加特判 不存在的话 就改为 0
            turnoverList.add(turnover);
        }

        turnoverReportVO.setTurnoverList(StringUtils.join(turnoverList, ","));
        return turnoverReportVO;
    }

    /**
     * 统计指定区间内的用户的数量
     * @param begin
     * @param end
     * @return
     */
    @Override
    public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {
        UserReportVO userReportVO = new UserReportVO();
        //---------------日期---------------
        List<LocalDate>dateList = new ArrayList<>(); // 用于存放begin 到 end 范围内的每天的日期
        //计算指定日期的后一天
        while(!begin.equals(end)) {
            dateList.add(begin);
            begin = begin.plusDays(1);
        }
        dateList.add(end);

        //---------------用户总量-------------------------
        List<Integer>newUserList = new ArrayList<>();
        //--------------总用户数量------------------------
        List<Integer>totalUserList = new ArrayList<>();

        for (LocalDate date : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            Map newUsersMap = new HashMap();
            Map totalUsersMap = new HashMap();
            newUsersMap.put("begin", beginTime);
            newUsersMap.put("end", endTime);
            totalUsersMap.put("end", beginTime); // 注意细节

            Integer newUsersCount = userMapper.countByMap(newUsersMap);
            Integer totalUsersCount = userMapper.countByMap(totalUsersMap);
            //判断一下是不是空的
            newUsersCount = newUsersCount == null ? 0 : newUsersCount;
            totalUsersCount = totalUsersCount == null ? 0 : totalUsersCount;

            newUserList.add(newUsersCount);
            totalUserList.add(totalUsersCount);
        }

        userReportVO.setNewUserList(StringUtils.join(newUserList, ","));
        userReportVO.setTotalUserList(StringUtils.join(totalUserList, ","));
        userReportVO.setDateList(StringUtils.join(dateList, ","));
        return userReportVO;
    }

    @Override
    public OrderReportVO getOrdersStatistics(LocalDate begin, LocalDate end) {
        OrderReportVO orderReportVO = new OrderReportVO();

        //---------------日期---------------
        List<LocalDate>dateList = new ArrayList<>(); // 用于存放begin 到 end 范围内的每天的日期
        //计算指定日期的后一天
        while(!begin.equals(end)) {
            dateList.add(begin);
            begin = begin.plusDays(1);
        }
        dateList.add(begin);

        Integer validOrderCount = 0;
        Integer totalOrderCount = 0;

        List<Integer>totalOrderCountList = new ArrayList<>();
        List<Integer>validOrderCountList = new ArrayList<>();

        for (LocalDate date : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            Map map = new HashMap();
            map.put("begin", beginTime);
            map.put("end", endTime);
            Integer t1 = orderMapper.getOrdesCountByMap(map);
            map.put("status", Orders.COMPLETED);
            Integer t2 = orderMapper.getOrdesCountByMap(map);

            validOrderCount += t2;
            validOrderCountList.add(t2);

            totalOrderCount += t1;
            totalOrderCountList.add(t1);
        }
        orderReportVO.setDateList(StringUtils.join(dateList, ","));
        totalOrderCount = totalOrderCount == 0 ? 1 : totalOrderCount;
        orderReportVO.setOrderCompletionRate(validOrderCount * 1.0 / totalOrderCount);
        orderReportVO.setOrderCountList(StringUtils.join(totalOrderCountList, ","));
        orderReportVO.setValidOrderCountList(StringUtils.join(validOrderCountList, ","));
        orderReportVO.setValidOrderCount(validOrderCount);
        orderReportVO.setTotalOrderCount(totalOrderCount);

        return orderReportVO;
    }

    /**
     * 查询销量排名top10
     * @param begin
     * @param end
     * @return
     */
    @Override
    public SalesTop10ReportVO getTop10(LocalDate begin, LocalDate end) {

        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);

        SalesTop10ReportVO salesTop10ReportVO = new SalesTop10ReportVO();
        List<Orders>ordersList = new ArrayList<>();

        ordersList = orderMapper.getOrdersByStatusAndDate(beginTime, endTime);
        Map<String, Integer>mp = new HashMap<>();
        List<numAndName>result = new ArrayList<>();

        for (Orders order : ordersList) {
            List<OrderDetail> orderDetailList = orderDetailMapper.getOrderDetailByOrderId(order.getId());
            OrderDetail orderDetail = orderDetailList.get(0);
            String name = orderDetail.getName();
            Integer num = orderDetail.getNumber();
            Integer t = mp.get(name) == null ? 0 : mp.get(name);
            num += t;
            mp.put(name, num);
        }
        Set<String> strings = mp.keySet();
        for (String string : strings) {
            result.add(new numAndName(string, mp.get(string)));
        }
        result.sort((o1, o2) -> o2.getNum() - o1.getNum());
        int t = 1;
        List<String>list1 = new ArrayList<>();
        List<Integer>list2 = new ArrayList<>();

        for (numAndName numAndName : result) {
            if(t > 10) break;
            list1.add(numAndName.getName());
            list2.add(numAndName.getNum());
            t ++ ;
        }
        salesTop10ReportVO.setNameList(StringUtils.join(list1, ","));
        salesTop10ReportVO.setNumberList(StringUtils.join(list2, ","));
        return salesTop10ReportVO;
    }

    /**
     * 报表导出
     * @param response
     */
    @Override
    public void exportBusinessData(HttpServletResponse response)  {
        // 查询数据库 获取营业数据 -- 最近30天的运营数据
        LocalDate begin = LocalDate.now().plusDays(-30);
        LocalDate end = LocalDate.now().plusDays(-1); // 到昨天 就可以了
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);
        //查询概览数据
        BusinessDataVO businessData = workspaceService.getBusinessData(beginTime, endTime);
        //获得输入流对象
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板"); // 不能带后缀?
        try {
          //  in = new FileInputStream(new File("src/main/resources/template/运营数据报表模板.xlsx"));
            in = new FileInputStream(new File("C:\\Users\\Lenovo\\Desktop\\sky-take-out\\cangqiong-takeout\\sky-server\\src\\main\\resources\\template\\运营数据报表模板.xlsx"));
            //基于模版文件 创建excel对象
            XSSFWorkbook excel = new XSSFWorkbook(in);
            //获取sheet页
            XSSFSheet sheet = excel.getSheetAt(0);
            //----------------------概览数据------------------------------------
            //填充数据 日期时间
            sheet.getRow(1).getCell(1).setCellValue("时间: " + begin + "至" + end); // 第二行
            XSSFRow row = sheet.getRow(3);//获得第4行
            row.getCell(2).setCellValue(businessData.getTurnover()); // 填充营业额
            row.getCell(4).setCellValue(businessData.getOrderCompletionRate()); // 订单完成率
            row.getCell(6).setCellValue(businessData.getNewUsers()); // 新增用户

            row = sheet.getRow(4); // 获的第5行
            row.getCell(2).setCellValue(businessData.getValidOrderCount()); // 有效订单数
            row.getCell(4).setCellValue(businessData.getUnitPrice()); // 平均客单价

            //--------------------明细数据------------------------------------------
            for(int i = 0; i < 30; ++ i ) {
                LocalDate date = begin.plusDays(i);
                //当天的订单数据
                BusinessDataVO businessDataVO = workspaceService.getBusinessData(LocalDateTime.of(date, LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX));
                row = sheet.getRow(7 + i);
                row.getCell(1).setCellValue(date + "");
                row.getCell(2).setCellValue(businessDataVO.getTurnover());// 营业额
                row.getCell(3).setCellValue(businessDataVO.getValidOrderCount());// 有效订单
                row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());// 订单完成率
                row.getCell(5).setCellValue(businessDataVO.getUnitPrice()); // 平均客单价
                row.getCell(6).setCellValue(businessDataVO.getNewUsers()); // 新增用户
            }
            //--------------------输出结果------------------------------------------
            // 通过输出流 把excel文件下载到客户端浏览器
            ServletOutputStream out = response.getOutputStream();
            excel.write(out); // 写回到客户端浏览器
            //关闭流
            excel.close();
            in.close();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class numAndName {
    private String name;
    private Integer num;
}
